/******************************************************************************
 * @file     wdt_test_startup.c
 * @version  V0.10
 * $Revision: 1 $
 * $Date: 21/02/23 9:23a $
 * @brief    IEC60730 Interrupt Test
 * @note
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (C) 2016-2020 Nuvoton Technology Corp. All rights reserved.
 ******************************************************************************/

#include <stdio.h>
#include "nuc980.h"
#include "IEC60730_CONTROL_PARAM.h"
#include "IEC60730_SAFETY_TEST_LIB.h"

extern uint32_t u32Timer0Cnt;
uint32_t volatile u32WdtInt;

/*-------------------------------------------*/
/*                init wdt                   */
/*-------------------------------------------*/
static uint32_t InitWdt(void)
//uint32_t InitWdt(void)
{
    /* unlock register */
    SYS_UnlockReg();

    /* select WDT clock source from clk_in/512 (12 MHz/512) */
    outpw(REG_CLK_DIVCTL8, (inpw(REG_CLK_DIVCTL8) & ~0x300) | 0x100);

    /* enable WDT engine clock */
    outpw(REG_CLK_PCLKEN0, inpw(REG_CLK_PCLKEN0) | 1); 

    /* Configure WDT settings and start WDT counting, Set WDT time out interval
       to 2^14 Twdt = 0.7 sec. Where Twdt = 12MHZ / 512 */
    WDT_Open(WDT_TIMEOUT_2POW14, WDT_RESET_DELAY_18CLK, TRUE, TRUE);

    /* init flag */
    u32WdtInt = FALSE;

    /* enable WDT interrupt function */
    WDT_EnableInt();

    return TRUE;
}

/*-------------------------------------------*/
/*                init timer0                */
/*-------------------------------------------*/
static void InitTimer0(void)
{
    /* select timer0 clock from clk_in (12 MHz) */
    outpw(REG_CLK_DIVCTL8, inpw(REG_CLK_DIVCTL8) & ~0x30000);

    /* enable ETIMER0 engine clock */
    outpw(REG_CLK_PCLKEN0, inpw(REG_CLK_PCLKEN0) | (1 << 8));

    /* set timer0 frequency to 1,000 HZ */
    ETIMER_Open(TIMER0, ETIMER_PERIODIC_MODE, 1000);

    /* clear timer count */
    u32Timer0Cnt = 0;
}

/*-------------------------------------------*/
/*                wdt test                   */
/*-------------------------------------------*/
uint8_t IEC60730_WDT_Test(void)
{
    uint8_t u8WDTTestPass;
    
    /* init timer0 and interrupt */
    InitTimer0();
    sysInstallISR(IRQ_LEVEL_1, IRQ_TIMER0, (PVOID)ETMR0_IRQHandler);
    sysSetLocalInterrupt(ENABLE_IRQ);
    ETIMER_EnableInt(TIMER0);
    sysEnableInterrupt(IRQ_TIMER0);

    /* start timer0 */
    ETIMER_Start(TIMER0);

    /* init WDT and interrupt */
    InitWdt();
    sysInstallISR(IRQ_LEVEL_1, IRQ_WDT, (PVOID)WDT_IRQHandler);
    sysSetLocalInterrupt(ENABLE_IRQ);
    sysEnableInterrupt(IRQ_WDT);

    /* wait WDT interrupt */
    while (u32WdtInt!=TRUE);

    /* disable wdt and its interrupt */	
    SYS_UnlockReg();
    WDT_Close();
    sysDisableInterrupt(IRQ_WDT);

    /* close timer0 and its interrupt */		
    ETIMER_Close(TIMER0);
    sysDisableInterrupt(IRQ_TIMER0);

    /* check timer0 count */
    /* WDT_duration = 700 msec, Timer0_freq = 1000 Hz 
        u32Timer0Cnt = WDT_duration*Timer0_freq/1000 = 700 */
    if((u32Timer0Cnt >= (WDT_DURATION*(TIMER0_STARTUP_FREQ/1000)-2) 
        && (u32Timer0Cnt <= (WDT_DURATION*(TIMER0_STARTUP_FREQ/1000)+2))))
        u8WDTTestPass = TEST_PASS;
    else
    {
        printf("cnt=%d\n", u32Timer0Cnt);
        u8WDTTestPass = TEST_FAIL;		
    }
    return u8WDTTestPass;
}

/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
